package org.an.proj.contacts.util;

import android.Manifest;
import android.content.ContentResolver;
import android.database.Cursor;
import android.os.AsyncTask;
import android.provider.CallLog;
import android.provider.ContactsContract;
import android.text.TextUtils;
import java.util.ArrayList;
import java.util.List;
import link.model.ContactInfo;
import org.an.ku.util.ToastUtil;
import org.an.proj.contacts.MyApplication;

/**
 * 创建时间：2016年09月01日18:34 <br>
 * 作者：fuchaoyang <br>
 * 描述：获取通话记录的helper
 */
public class ContactsHelper {
  private QueryTask mTask;
  private int mTotalCount = 0;
  // 记录游标位置
  private int mCursorOffset = -1;
  private IResult<ContactInfo> mIResult;

  public ContactsHelper(IResult<ContactInfo> listener) {
    mIResult = listener;
  }

  public int getTotalCount() {
    return mTotalCount;
  }

  /**
   * 去除空格，-等只保留数字
   *
   * @return null if phoneNum = null
   */
  public static String getValid(String phoneNum) {
    if (phoneNum == null) return null;
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < phoneNum.length(); i++) {
      char c = phoneNum.charAt(i);
      if (c >= '0' && c <= '9') {
        sb.append(c);
      }
    }
    return sb.toString();
  }

  /**
   * 获取指定联系人的全部电话
   *
   * @param contactId 联系人id
   */
  public static List<String> getPhonesFromContactId(String contactId) {
    List<String> phones = new ArrayList<>();
    // 获得联系人的电话号码列表
    String[] projection = new String[] { ContactsContract.CommonDataKinds.Phone.NUMBER };
    Cursor phoneCursor = MyApplication.getInstance()
        .getContentResolver()
        .query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, projection,
            ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "=" + contactId, null, null);
    if (phoneCursor != null && phoneCursor.moveToFirst()) {
      do {
        //遍历所有的联系人下面所有的电话号码
        String phoneNumber = phoneCursor.getString(
            phoneCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
        phoneNumber = getValid(phoneNumber);
        phones.add(phoneNumber);
      } while (phoneCursor.moveToNext());
      phoneCursor.close();
    }
    return phones;
  }

  public static String[] getContactIdAndNameFromPhone(String phoneNum) {
    String other = getValid(phoneNum);
    ContentResolver resolver = MyApplication.getInstance().getContentResolver();
    // 查询电话表
    Cursor cursor =
        resolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, new String[] {
            ContactsContract.CommonDataKinds.Phone.NUMBER,
            ContactsContract.CommonDataKinds.Phone.CONTACT_ID,
            ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME
        }, null, null, null);
    if (cursor != null && cursor.moveToFirst()) {
      do {
        // 取表中的所有电话
        String num =
            cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
        String valid = getValid(num);
        // 如果匹配到，记录contactId和DisplayName
        if (TextUtils.equals(other, valid)) {
          String[] data = new String[2];
          data[0] = cursor.getString(
              cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID));
          data[1] = cursor.getString(
              cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
          return data;
        }
      } while (cursor.moveToNext());
      cursor.close();
    }
    return null;
  }

  public void loadCallRecord() {
    loadCallRecord(-1);
  }

  /**
   * @param limit limit
   */
  public void loadCallRecord(int limit) {
    if (mTask != null) {
      if (mTask.getStatus() != null && mTask.getStatus() != AsyncTask.Status.FINISHED) {
        return;
      }
    }
    mTask = new QueryTask(limit);
    mTask.execute();
  }

  /**
   * 查询所有的通话记录，不分页
   */
  public List<ContactInfo> queryCallRecord() {
    return queryCallRecord(-1);
  }

  /**
   * 分页
   *
   * @param limit limit
   */
  public List<ContactInfo> queryCallRecord(int limit) {
    List<ContactInfo> list = new ArrayList<>();
    String[] projection = { CallLog.Calls.NUMBER };
    // 获取cursor并没有真正的查找，并不耗时，执行cursor.moveXX时才真正的查询（耗时）
    if (AppUtil.checkPermission(Manifest.permission.READ_CALL_LOG)) {
      MyApplication.getInstance().getHandler().post(new Runnable() {
        @Override public void run() {
          ToastUtil.toast(MyApplication.getInstance(), "READ_CALL_LOG权限被拒绝");
        }
      });
      return list;
    }
    Cursor cursor = MyApplication.getInstance()
        .getContentResolver()
        .query(CallLog.Calls.CONTENT_URI, projection, null, null, CallLog.Calls.DEFAULT_SORT_ORDER);
    if (cursor != null && cursor.getCount() > 0) {
      mTotalCount = cursor.getCount();
      // 由于这里去重了，导致这个 moveToPosition并不是limit个数，即有可能查了25个，有5个是重复的，list.size=20
      for (int i = 0; i < mTotalCount && mCursorOffset < mTotalCount - 1; i++) {
        mCursorOffset++;
        cursor.moveToPosition(mCursorOffset);
        String number = cursor.getString(cursor.getColumnIndex(CallLog.Calls.NUMBER));
        handle(list, number);
        if (limit != -1 && list.size() >= limit) {
          break;
        }
        // 缓存的名称与电话号码，这个会一直为null
        // String cachedName = cursor.getString(cursor.getColumnIndex(CallLog.Calls.CACHED_NAME));
      }
      cursor.close();
    } else {
      mTotalCount = 0;
    }
    return list;
  }

  private void handle(List<ContactInfo> list, String phoneNum) {
    boolean hasPhone = false;
    for (ContactInfo info : list) {
      //  只处理limit条数据中的重复数据，并不与全部比较
      if (info.phones != null && info.phones.contains(phoneNum)) {
        hasPhone = true;
        break;
      }
    }
    // 当前列表数据中没有找到这个电话
    if (!hasPhone) {
      // 如果没有则添加，取联系人id，判断是否存在该联系人
      String[] data = getContactIdAndNameFromPhone(phoneNum);
      ContactInfo info = new ContactInfo();
      if (data != null) {
        info.id = data[0];
        int index = list.indexOf(info);
        if (index != -1) {
          // 已经存在这个联系人，直接通过id查询全部联系方式
          list.get(index).phones = ContactsHelper.getPhonesFromContactId(data[0]);
        } else {
          // 不存在这个联系人，直接创建一个
          info.name = data[1];
          info.phones = ContactsHelper.getPhonesFromContactId(data[0]);
          list.add(info);
        }
      } else {
        // 通讯录中没有这个联系人
        //info.name = phoneNum;
        info.phones = new ArrayList<>();
        info.phones.add(phoneNum);
        list.add(info);
      }
    }
  }

  public void onDestroy() {
    if (mTask != null) {
      mTask.cancel(true);
    }
  }

  private class QueryTask extends AsyncTask<Void, Void, List<ContactInfo>> {

    private int limit;

    public QueryTask(int limit) {
      this.limit = limit;
    }

    @Override protected void onPostExecute(List<ContactInfo> list) {
      if (mIResult != null) {
        mIResult.loadFinished(mCursorOffset + 1 < mTotalCount, list);
      }
    }

    @Override protected List<ContactInfo> doInBackground(Void... params) {
      return queryCallRecord(limit);
    }
  }

  public interface IResult<T> {
    void loadFinished(boolean hasMore, List<T> list);
  }
}
